package it.trekker.activities;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import it.trekker.R;
import it.trekker.db.Excursion;
import it.trekker.db.ExcursionDAO;
import it.trekker.db.ExcursionCoordinate;
import it.trekker.db.ExcursionCoordinateDAO;
import it.trekker.statistics.GPSStatistics;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.TextView;

public class ExcursionStatisticsActivity extends Activity {
	
	private static final String TAG = ExcursionStatisticsActivity.class.getSimpleName();
	
	// GUI components
	private TextView excursionName_tv = null;
	private TextView date_tv = null;
	private TextView startTime_tv = null;
	private TextView endTime_tv = null;
	private TextView meanPace_tv = null;
	private TextView startAltitude_tv = null;
	private TextView endAltitude_tv = null;
	private TextView differenceTot_tv = null;
	private TextView differenceUp_tv = null;
	private TextView differenceDown_tv = null;
	private TextView distance_tv = null;
	private TextView time_tv = null;
	private TextView steps_tv = null;
	
//	private ProgressDialog progressDialog;
	
	private Excursion excursion;
	
	private GPSStatistics statistics = null;
	private ExcursionDAO excursionDAO = null;
	private ExcursionCoordinateDAO gpsCoordinateDAO = null;

	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		setContentView(R.layout.statistics_layout);
		
		excursionName_tv = (TextView) findViewById(R.id.stat_excursion_name);
		date_tv = (TextView) findViewById(R.id.stat_date);
		startTime_tv = (TextView) findViewById(R.id.stat_starttime);
		endTime_tv = (TextView) findViewById(R.id.stat_endtime);
		meanPace_tv = (TextView) findViewById(R.id.stat_meanpace);
		startAltitude_tv = (TextView) findViewById(R.id.stat_startaltitude);
		endAltitude_tv = (TextView) findViewById(R.id.stat_endaltitude);
		differenceTot_tv = (TextView) findViewById(R.id.stat_difference_tot);
		differenceUp_tv = (TextView) findViewById(R.id.stat_difference_up);
		differenceDown_tv = (TextView) findViewById(R.id.stat_difference_down);
		distance_tv = (TextView) findViewById(R.id.stat_distance);
		time_tv = (TextView) findViewById(R.id.stat_time);
		steps_tv = (TextView) findViewById(R.id.stat_steps);
		
		// Load data saved in onSaveInstanceState()
		if(savedInstanceState != null) {
			if(savedInstanceState.containsKey("statisticsManager"))
				statistics = (GPSStatistics) savedInstanceState.getSerializable("statisticsManager");
			if(savedInstanceState.containsKey("excursion"))
				excursion = (Excursion) savedInstanceState.getSerializable("excursion");
		}
		
		if(statistics == null || excursion == null) {	// Calculate statistics
			statistics = new GPSStatistics();
			excursionDAO = new ExcursionDAO(this);
			gpsCoordinateDAO = new ExcursionCoordinateDAO(this);
			
//			progressDialog = ProgressDialog.show(this, "Working..." , "Calculating statistics");
//			Thread thread = new Thread(this);
//			thread.start();
			
			Bundle params = getIntent().getExtras();
			int excursionId = params.getInt("excursion_id");

			new AsyncCalculating().execute(excursionId);
		}
		else {	// Statistics already calculated: update views
			updateViews();
		}
	}
	
	@Override
	protected void onResume() {
		super.onResume();
	}
	
	@Override
	protected void onPause() {
		super.onPause();
	}
	
	@Override
	protected void onDestroy() {
		super.onDestroy();
	}
	
	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		
		if(statistics != null)
			outState.putSerializable("statisticsManager", statistics);
		if(excursion !=  null)
			outState.putSerializable("excursion", excursion);
	}
	
	

	private void updateViews() {
		
		DateFormat dateDf = new SimpleDateFormat("dd/MM/yy");
		DateFormat timeDf = new SimpleDateFormat("HH:mm:ss");
//		timeDf.setTimeZone(TimeZone.getTimeZone("Europe/Rome"));
//		
//		for(String id : TimeZone.getAvailableIDs()) {
//			Log.d(TAG, "TimeZone: " + id);
//		}
//		Log.d(TAG, TimeZone.getDefault().getDisplayName());
		
		excursionName_tv.setText(excursion.getName());
		date_tv.setText(dateDf.format(excursion.getDate()));
		
		steps_tv.setText(String.valueOf(excursion.getSteps()));
		
		Date startTime = statistics.getStartTime();
		Date endTime = statistics.getEndTime();
		String startTime_str = null;
		String endTime_str = null;
		
		if(startTime == null) {
			startTime_str = "-";
		}
		else {
			startTime_str = timeDf.format(startTime);
		}
		
		if(endTime == null) {
			endTime_str = "-";
		}
		else {
			endTime_str = timeDf.format(endTime);
		}
		
		startTime_tv.setText(startTime_str);
		endTime_tv.setText(endTime_str);
		
		double meanPace = statistics.getMeanPace();
		String meanPace_str;
		if(meanPace == GPSStatistics.UNDEFINED_PACE) {
			meanPace_str = "-";
		}
		else if(meanPace < 0) {
			meanPace_str = "error";
		}
		else {
			meanPace_str = String.format("%.2f", meanPace);
		}
		meanPace_tv.setText(meanPace_str);
		
//		double totDiff = statistics.getTotAltitudeDifference();
//		String totDiff_strFormatted = String.format("%.2f", totDiff);
//		String totDiff_str;
//		if(totDiff > 0) {
//			totDiff_str = "+" + totDiff_strFormatted;
//		}
//		else {
//			totDiff_str = totDiff_strFormatted;
//		}
//		
//		differenceTot_tv.setText(totDiff_str);	// m
		differenceTot_tv.setText(String.format("%+.2f", statistics.getTotAltitudeDifference()));	// m
		differenceUp_tv.setText(String.format("%+.2f", statistics.getUpAltitudeDifference()));	// m
		differenceDown_tv.setText(String.format("%+.2f", statistics.getDownAltitudeDifference()));	// m
		distance_tv.setText(String.format("%.3f", statistics.getDistance()/1000));	// Km
		
		String startAltitude_str;
		if(statistics.getStartAltitude() == GPSStatistics.UNDEFINED_ALTITUDE) {
			startAltitude_str = "-";
		}
		else {
			startAltitude_str = String.format("%.2f", statistics.getStartAltitude());
		}
		startAltitude_tv.setText(startAltitude_str);
		
		String endAltitude_str;
		if(statistics.getCurrentAltitude() == GPSStatistics.UNDEFINED_ALTITUDE) {
			endAltitude_str = "-";
		}
		else {
			endAltitude_str = String.format("%.2f", statistics.getCurrentAltitude());
		}
		endAltitude_tv.setText(endAltitude_str);
		
		long time = statistics.getTime();	// milliseconds
		long hours = time/(1000*60*60);
		long minutes = time/(1000*60) - hours*60;
		long seconds = time/1000 - hours*60*60 - minutes*60;
		String hours_str;
		String minutes_str;
		String seconds_str;
		
		if(hours < 10) {
			hours_str = "0" + hours;
		}
		else {
			hours_str = String.valueOf(hours);
		}
		
		if(minutes < 10) {
			minutes_str = "0" + minutes;
		}
		else {
			minutes_str = String.valueOf(minutes);
		}
		
		if(seconds < 10) {
			seconds_str = "0" + seconds;
		}
		else {
			seconds_str = String.valueOf(seconds);
		}
		
		time_tv.setText(hours_str + ":" + minutes_str + ":" + seconds_str);
		
		
	}

	
//	private void updateStatistics() {
//		Bundle params = getIntent().getExtras();
//		int excursionId = params.getInt("excursion_id");
//		
//		excursionDAO.open();
//		excursion = excursionDAO.getExcursion(excursionId);
//		excursionDAO.close();
//		
//		gpsCoordinateDAO.open();
//		List<GPSCoordinate> locations = gpsCoordinateDAO.getAllCoordinatesByExcursion(excursionId);
//		gpsCoordinateDAO.close();
//		
//		statistics.setLastLocations(locations);
//		statistics.update();
//	}
	
	
	
	
	
	//***********************************************************************//
	//************************* Loading data thread *************************//
	//***********************************************************************//
	
//	private static final int UPDATE_END = 0;
//	@Override
//	public void run() {
//		updateStatistics();		
//		handler.sendEmptyMessage(UPDATE_END);
//	}
//	
//	
//	private Handler handler = new Handler() {
//		@Override
//		public void handleMessage(Message msg) {
//			switch(msg.what) {
//				case UPDATE_END:	
//					progressDialog.dismiss();
//					updateViews();
//					break;
//				default:
//					super.handleMessage(msg);
//					break;
//			}
//		};
//	};
	
	
	private class AsyncCalculating extends AsyncTask<Integer, Void, Boolean> {

		private ProgressDialog progressDialog;
		
		@Override
		protected void onPreExecute() {
			progressDialog = ProgressDialog.show(ExcursionStatisticsActivity.this, "Working..." , "Calculating statistics");
		}
		
		@Override
		protected Boolean doInBackground(Integer... params) {
			excursionDAO.open();
			excursion = excursionDAO.getExcursion(params[0]);
			excursionDAO.close();
			
			gpsCoordinateDAO.open();
			List<ExcursionCoordinate> locations = gpsCoordinateDAO.getAllCoordinatesByExcursion(params[0]);
			gpsCoordinateDAO.close();
			
			statistics.setLastLocations(locations);
			statistics.update();
			
			return true;
		}
		
		@Override
		protected void onPostExecute(Boolean result) {
			updateViews();
			progressDialog.dismiss();
		}
		
	}
}
